class ThsApiBase {

    name()
    {
        return "base";
    }

    constructor() {
        this.bind = this.cefCreateSession();
        this.sessionId = this.bind.sessionId;
        console.log(this.bind);
        //this.promise = this.cefRequest("constructor").then((connectPointer) => this.connectPointer = connectPointer);
    }

    cefCreateSession()
    {
        return window.cefNewSession(this.name());
    }

    //建议用Promise 而不是通过传入回掉函数的方式
    async cefRequest( method, params, options, onSuccess, onFail)
    {
        return ThsApiBase.cefRequest(this.name(), method, params, options, onSuccess, onFail, this.sessionId);
    }

    static cefRequest(name, method, params, options = {timeout:30000, persistent:false}, onSuccess, onFail, sessionId)
    {
		//console.log('name=', name, 'method=', method, 'params=', params);
       if (params &&　Object.prototype.toString.call(params) != '[object Array]')
       {
           //console.log('not array...');
           params = [params];//统一转化为数组进行处理
       }
       let request = {
            v:"1.0",
            method:name + '.' + method,
            params:params,
            sessionId:sessionId,
        };
        let onCefSuccess;
        let onCefFail;
        let promise = new Promise(function(resolve, reject) {
            let timeoutTimer = null;
            if (!options.persistent && !onSuccess)
            {
                timeoutTimer = setTimeout(()=> {window.cefQueryCancel(promise.request_id); reject(Error('Time out'));console.log('timeout: name=', name, 'method=', method, 'params=', params);;}, options.timeout);
            }

            onCefSuccess = function(response)
            {
                if (onSuccess)
                {
                    onSuccess(response);
                }

                if  (!options.persistent)
                {
                    resolve(response);
                }
                //console.log('success: name=', name, 'method=', method, 'params=', params, 'response=', response);

                if (timeoutTimer)
                {
                    clearTimeout(timeoutTimer);
                }
            }

            onCefFail = function(error_code, error_msg)
            {
                console.log('fail: name=', name, 'method=', method, 'params=', params, 'error_code=', error_code, 'error_msg=', error_msg, 'sessionId=', sessionId);
                reject(Error(error_code + ':' + error_msg));
                if (timeoutTimer)
                {
                    clearTimeout(timeoutTimer);
                }
                if (onFail)
                {
                    onFail(error_code, error_msg);
                }
            }

        })
        let query = {
            request: JSON.stringify(request),
            persistent: options.persistent,
            onSuccess: onCefSuccess,
            onFailure: onCefFail,
        };
        promise.request_id = window.cefQuery(query);

        return promise;
    }
}

class ThsExternal extends ThsApiBase {

    static name() {
        return "external";
    }

    static cefRequest(method, params, options, onSuccess, onFail, sessionId)
    {
        return ThsApiBase.cefRequest(ThsExternal.name(), method, params, options, onSuccess, onFail, sessionId);
    }

    //event: 'onshow', and so on...
    static async registerEvent(event, onevent){
        return this.cefRequest("registerEvent", event, {timeout:-1, persistent:true}, onevent);
    }

    static async getModulePath()
    {
        return this.cefRequest("getModulePath");
    }

    static async getUserPath()
    {
        return this.cefRequest("getUserPath");
    }

    static async clickButton(id)
    {
        return this.cefRequest("clickButton", id);
    }

    static async closeWindow()
    {
        return this.cefRequest("closeWindow")
    }

    static async setWindowWidth(params)
    {
        return this.cefRequest("setWindowWidth", params);
    }

    static async setWindowRect(params)
    {
        console.log('ThsExternal.setWindowRect, params=', params);
        return this.cefRequest("setWindowRect", params);
    }

    static async IsLeftBarVisible()
    {
        return this.cefRequest("IsLeftBarVisible");
    }

    static async ShowLeftBar(show)
    {
        return this.cefRequest("ShowLeftBar", show);
    }

    static async offsetWindowRect(params)
    {
         console.log('ThsExternal.offsetWindowRect, params=', params);
        return this.cefRequest("offsetWindowRect", params);
    }

    static async minimizeWindow()
    {
        return this.cefRequest("minimizeWindow");
    }

    static async closeWebDlg()
    {
        return this.cefRequest("closeWebDlg");
    }

    static async moveWindowByMessage(type)
    {
        return this.cefRequest("moveWindowByMessage", type);
    }
}

class ThsQuote extends ThsApiBase {
    constructor() {
        super();
    }

    name()
    {
        return "quote";
    }

    static async cefRequest(method, params, options, onSuccess, onFail, sessionId)
    {
        return ThsApiBase.cefRequest(ThsQuote.name(), method, params, options, onSuccess, onFail, sessionId);
    }

    async getServerTime()
    {
        return  this.cefRequest("getServerTime");
    }

    async syncStockList(param)
    {
        return this.cefRequest('syncStockList', param);
    }

    async isTradeTime(code)
    {
        return this.cefRequest("isTradeTime", code);
    }

    async getSHTradeDate(lDate)
    {
        return this.cefRequest("getSHTradeDate", lDate);
    }

    async getPreSHTradeDate(lDate)
    {
        return this.cefRequest("getPreSHTradeDate", lDate);
    }

    async getHxCurPageID()
    {
        return this.cefRequest('getHxCurPageID');
    }

    async getHxCurPageName()
    {
        return this.cefRequest('getHxCurPageName');
    }

    // async request(params)
    // {
    //     return this.cefRequest("request", params);
    // }
    async request(params)
    {
        return this.cefRequest("request", params, {timeout:30000, persistent:false}, params.onready);
    }

//区间统计
    async AreaStatConRequest(params)
    {
        return this.cefRequest("AreaStatConRequest", params);
    }

    async SetAreaStatTime(params)
    {
        return this.cefRequest("SetAreaStatTime", params);
    }
    //coco修改，增加参数
    async StartGetAreaStatData(code)
    {
        return this.cefRequest("StartGetAreaStatData",code);
    }

    async getStatData(params)
    {
        return this.cefRequest("getStatData", params);
    }

    async AreaStatRequest(params)
    {
        return this.cefRequest("AreaStatRequest", params);
    }
//区间统计 end

    async getStockBlock(codewithmarket)
    {
        return this.cefRequest("getStockBlock", codewithmarket);
    }

    async getData(params)
    {
        console.log("warning:deprecated, getData2 is recommended");
        //多代码情况下 返回值与getData2形式有不同， 不好在js层做转换，为迁移方便， 旧接口暂时保留， 但是不推荐新项目继续使用本接口
        // //参数转换为新接口参数形式(time格式变动) 返回值加括号
        // let newparams = JSON.parse(JSON.stringify(params));
        // newparams.time = {
        //     begin:params.time,
        //     end:params.time,
        // }
        // console.log('getData: params=', params);
        // return '(' + await this.getData2(newparams) + ')';
        return this.cefRequest("getData", params);
    }

    async getData2(params)
    {
        return this.cefRequest("getData2", params);
    }


    //注册推送场景 不用promise
    async registerPush(params)
    {
      var codes = params.code;
      var onPushDataReady = params.onready;

 /*  暂时无视以下注释！！！！！！！！！！
      // 参数规则, 最后会将多个参数转换为数组, 客户端收到后解析拆回为多个各有含义的参数， 比如下面的requestUpDownLimitData,
        // 但是为了避免原本就是数组的参数也被拆掉，比如codes就可能是一个类型是数组的单个参数， 被拆开成多个， 就含义不对了， 为了防止这种情况， 需要再用[]包一层
*/
        return this.cefRequest("registerPush", codes, {timeout:-1, persistent:true}, onPushDataReady);
    }

    async unregisterPush(codes)
    {
        return this.cefRequest("unregisterPush", codes);
    }

    async requestUpDownLimitData(period, begin, end)
    {
        return this.cefRequest("requestUpDownLimitData", [period, begin, end]);
    }

    async requestZxData(params)
    {
        return this.cefRequest("requestZxData", params);
    }

    async IsStockOrIndex(stock)
    {
        return this.cefRequest("IsStockOrIndex", stock);
    }

    async getStockCode(code)
    {
        return this.cefRequest("getStockCode", code);
    }

    async getStockType(code)
    {
        return this.cefRequest("getStockType", code);
    }

    async getPeriodNum(params)
    {
        return this.cefRequest("getPeriodNum", params);
    }

    async getIndexAndIndustry(code)
    {
        //console.log('getIndexAndIndustry code=', code);
        return this.cefRequest("getIndexAndIndustry", code);
    }

    async GetCodeDecimal(params)
    {
        return this.cefRequest("GetCodeDecimal", params);
    }

    async getThsIndexType(code)
    {
        return this.cefRequest("getThsIndexType", code);
    }
    //coco修改，将switchPageByUrl改为switchPageByURL
    async switchPageByURL(params)
    {
        return this.cefRequest("switchPageByURL", params);
    }

    async switchPage(params)
    {
        return this.cefRequest("switchPage", params);
    }

    async getSelectedTab()
    {
        return this.cefRequest("GetSelectedTab");
    }

    async switchCode(code)
    {
        return  this.cefRequest("switchCode", code);
    }
}

class ThsUtil extends ThsApiBase {

    constructor() {
        super();
    }

    name(){
        return "util";
    }

    static cefRequest(method, params, options, onSuccess, onFail, sessionId)
    {
        return ThsApiBase.cefRequest(ThsUtil.name(), method, params, options, onSuccess, onFail, sessionId);
    }


    async getSkinName()
    {
        return this.cefRequest("getSkinName");
    }
    //coco修改，新增type参数
    async getMacAddress(type)
    {
        return this.cefRequest("getMacAddress",type);
    }

    async getHxVer()
    {
        return this.cefRequest("getHxVer");
    }

    async openAlert(key)
    {
        return this.cefRequest("openAlert", key);
    }

    async openAppWebDlg(url)
    {
        return this.cefRequest("openAppWebDlg", url);
    }

    async addCodeToBlock(codes)
    {
        return this.cefRequest("addCodeToBlock", codes);
    }

    async getFormulaContentById(id)
    {
        return this.cefRequest("getFormulaContentById", id);
    }

    async modLocalAlertCfg(formulaID)
    {
        return this.cefRequest("modLocalAlertCfg", formulaID);
    }

    async setDefaultAlertMode(mode)
    {
        return this.cefRequest("setDefaultAlertMode", mode);
    }

    async openNoFrameWebDlg(url)
    {
        return this.cefRequest("openNoFrameWebDlg", url);
    }

    async getStockFilterDays()
    {
        return this.cefRequest("getStockFilterDays");
    }

    async registerEventNotify(type, onEvent)
    {
        return this.cefRequest("registerEventNotify", type, {timeout:-1, persistent:true}, onEvent);
    }

    async getBlockStockByID(blockid)
    {
        return this.cefRequest("getBlockStockByID", blockid);
    }

    async openURL(url, type)
    {
        return this.cefRequest("openURL", [url, type]);
    }

    async showPSWebDlg(obj)
    {
      return this.cefRequest("showPSWebDlg", obj);
    }

    async closePSWebDlg(id)
    {
      return this.cefRequest("closePSWebDlg", id);
    }

    async resizePSWebDlg(id, width, height)
    {
      return this.cefRequest("resizePSWebDlg", [id, width, height]);
    }

    async getSelfBlockMessage()
    {
      return this.cefRequest("getSelfBlockMessage");
    }

    async getBlockStockByID(blockId)
    {
      return this.cefRequest("getBlockStockByID", blockId);
    }

    async getScreenCaptureFileName(filePath)
    {
      return this.cefRequest("getScreenCaptureFileName", filePath);
    }

    async getFileBase64(encryptFilePath)
    {
      return this.cefRequest("getFileBase64", encryptFilePath);
    }

    async deleteFile(filePath)
    {
      return this.cefRequest("deleteFile", filePath);
    }

    async formPreFinishPay()
    {
      return this.cefRequest("formPreFinishPay");
    }

    async findFuncIdByPlatformId(platId)
    {
      return this.cefRequest("findFuncIdByPlatformId", platId);
    }

    async strategyBuy(xmlStr)
    {
      return this.cefRequest("strategyBuy", xmlStr);
    }

    async clearStrategyBuy()
    {
      return this.cefRequest("clearStrategyBuy");
    }

    async qltfuquan()
    {
      return this.cefRequest("qltfuquan");
    }

    async qltfuquancancel()
    {
      return this.cefRequest("qltfuquancancel");
    }

    async getfuquanstate()
    {
      return this.cefRequest("getfuquanstate");
    }

    async WriteAppCenterSynContent(strContent)
    {
      return this.cefRequest("WriteAppCenterSynContent", strContent);
    }

    async ReadAppCenterSynContent()
    {
      return this.cefRequest("ReadAppCenterSynContent");
    }

    async getUserGroupID(nUserGroupType)
    {
      return this.cefRequest("getUserGroupID", nUserGroupType);
    }

    async openAppCenterIndexDlg(url)
    {
      return this.cefRequest("openAppCenterIndexDlg", url);
    }

}

class ThsPassport extends ThsApiBase
{

    name(){
       return "passport";
    }

    static async cefRequest(method, params, options, onSuccess, onFail, sessionId)
    {
        return ThsApiBase.cefRequest(ThsPassport.name(), method, params, options, onSuccess, onFail, sessionId);
    }

    async get(key)
    {
        return this.cefRequest("get", key);
    }

    async getAccountInfo()
    {
        return this.cefRequest("getAccountInfo");
    }

    async getAccountAllInfo(account)
    {
        return this.cefRequest("getAccountAllInfo", account);
    }

    //coco修改，去除里面的account,估计作者笔误
    async selfIndustries()
    {
        return this.cefRequest("selfIndustries");
    }

    async getPassword()
    {
        return this.cefRequest("getPassword");
    }

    async IsLevel2User()
    {
        return this.cefRequest("IsLevel2User");
    }

    async selfStocks()
    {
        return this.cefRequest("selfStocks");
    }

    async holdStocks()
    {
        return this.cefRequest("holdStocks");
    }

    async curStock()
    {
        return this.cefRequest("curStock");
    }

    async getPassport(type)
    {
        return this.cefRequest("getPassport", type);
    }

    async getSignature(type)
    {
        return this.cefRequest("getSignature", type);
    }

    async getMarketCode(code)
    {
        return this.cefRequest("getMarketCode", code);
    }

    async getPublicKey()
    {
        return this.cefRequest("getPublicKey");
    }

    async getSessionid()
    {
        return this.cefRequest("getSessionid");
    }

    async updateSessionid()
    {
        return this.cefRequest("updateSessionid");
    }
}



class ThsFileReader extends ThsApiBase
{

    name(){
        return "fileReader";
    }

    async open(filePath)
    {
        return this.cefRequest('open', filePath);
    }

    async read()
    {
        return this.cefRequest('read');
    }

    async readBin()
    {
        return this.cefRequest('readBin');
    }

    async readDes()
    {
        return this.cefRequest('readDes');
    }

    async close()
    {
        return this.cefRequest('close');
    }
}

class ThsFileWriter extends ThsApiBase
{

    name(){
        return "fileWriter";
    }

    async open(filePath)
    {
        return this.cefRequest('open', filePath);
    }

    //save as utf8
    async write(strContent)
    {
        return this.cefRequest('write', strContent);
    }

    //save as raw
    async writeBin(strContent)
    {
        return this.cefRequest('writeBin', strContent)
    }

    //save as encrypted
    async writeDes(strContent)
    {
        return this.cefRequest('writeDes', str)
    }

    async close()
    {
        return this.cefRequest('close');
    }

}



window.ThsExternal = ThsExternal;
window.ThsQuote = ThsQuote;
window.ThsUtil = ThsUtil;
window.ThsPassport = ThsPassport;
window.ThsFileReader = ThsFileReader;
window.ThsFileWriter = ThsFileWriter;
